// Project: 27MUART_T
// FileName: 27MUART_T

#include <p18cxxx.h>
#include <delays.h>
#include <stdio.h>
#include <i2c.h>
#include <usart.h>


#pragma config FOSC=HSPLL_HS, PLLDIV=5, CPUDIV=OSC1_PLL2
#pragma config USBDIV=2, PWRT=ON, FCMEN=ON, IESO=ON
#pragma config BOR=ON, BORV=2, WDT=OFF, LVP=OFF, VREGEN=ON
#pragma config MCLRE=OFF, PBADEN=OFF, WDTPS=1024
#pragma config LPT1OSC=OFF, CCP2MX=OFF, DEBUG=OFF

#pragma config CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF, CPB=OFF
#pragma config CPD=OFF, WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF
#pragma config WRTB=OFF, WRTC=OFF, WRTD=OFF, EBTR0=OFF
#pragma config EBTR1=OFF, EBTR2=OFF, EBTR3=OFF, EBTRB=OFF


#define lcd_DB LATB
#define lcd_E LATBbits.LATB3
#define lcd_RS LATBbits.LATB2


#define Delay_50uS Delay100TCYx(6)
#define Delay_1mS Delay1KTCYx(12)
#define Delay_2mS Delay1KTCYx(24)
#define Delay_5mS Delay10KTCYx(6)
#define Delay_10mS Delay10KTCYx(12)
#define Delay_20mS Delay10KTCYx(24)
#define Delay_100mS Delay10KTCYx(120)



const unsigned char CN1[] = {
1,0,1,0,0,0};
const unsigned char CN2[] = {
1,0,0,0,1,1};
const unsigned char CN3[] = {
0,1,1,0,0,0};
const unsigned char CN4[] = {
0,0,1,1,0,1};
unsigned char z1, z2, z3, z4;
unsigned char CNw0, CNw1, CNw2, CNw3, CNw4, CNw5;
unsigned int CNr0, CNr1, CNr2, CNr3, CNr4, CNr5;

unsigned int s, sss, x, sh;
unsigned char si;
unsigned int ss[10], xx[6], X[6];

unsigned long b, sum, summ, rdd;
unsigned int n, j, jj, k, kk;
unsigned char N, sw, st, i, ii, iii, pw, tr;
unsigned char a0, a1, a2, a3;
unsigned char wd, wdl, wdh, wdhh;
unsigned int rd, rdl, rdh, rdhh;
unsigned char suml, sumh, sumhh;

unsigned char buf[25];
unsigned char a[9];

char card[] = "Card in ";
char input[] = "input data ";
char num[] = "N=";
char blank[] = " ";
char check[] = "check: ";
char trans[] = "trans* ";
char transed[] = "transed ! ";
char cleared[] = "cleared ! ";


void lcd_w4(char asci);
void lcd_c4(char cmd);
void lcd_clr(void);
void lcd_init(void);
void lcd_puts(char *s);
void lcd_locate(char y,char x);

void lcd_putf(unsigned long f);
void lcd_putfLow(unsigned long f);
void lcd_putfPre(unsigned long f);

void UserInit(void);
void lcd_Init(void);

void high(void);
void low(void);

#pragma interrupt high
#pragma interruptlow low
#pragma code H_vect = 0x0008
void H_isr(void){
_asm goto high _endasm
}
#pragma code L_vect = 0x0018
void L_isr(void){
_asm goto low _endasm
}
#pragma code



void high(){
}
void low(){
}





void lcd_w4(char c){
lcd_DB = (c & 0xF0) | (lcd_DB & 0x0F);
lcd_E = 1;
Delay10TCYx(20);
lcd_E = 0;
}

void lcd_c4(char c){
lcd_RS = 0;
lcd_w4(c);
lcd_w4(c<<4);
if(c & 0xFC)
Delay_50uS;
else
Delay_2mS;
}

void lcd_clr(void){
lcd_c4(0x01);
}

void lcd_locate(char y, char x){
unsigned char p;
switch(y & 0x03){
case 0: p=0x80; break;
case 1: p=0xC0; break;
case 2: p=0x94; break;
case 3: p=0xD4; break;
}
lcd_c4(p += x);
}

void lcd_putchr(char c){
lcd_RS = 1;
lcd_w4(c);
lcd_w4(c<<4);
Delay_50uS;
}

void lcd_puts(char *s){
while(*s)
lcd_putchr(*s++);
}



void lcd_putui(
unsigned long ui, unsigned char d){

unsigned char i;
unsigned char buf[9];

for(i = 0; i < 9; i++)
buf[i] = ' ';
i = 8;
do {
buf[i] = (ui % 10) + '0';
ui = ui / 10;
i--;
} while(ui > 0);

for(i = (9 - d); i < 9; i++)
lcd_putchr(buf[i]);
}


void lcd_putuit(
unsigned long ui, unsigned char d){

unsigned char i;
unsigned char buf[2];

for(i = 0; i < 2; i++)
buf[i] = ' ';
i = 1;
do {
buf[i] = (ui % 10) + '0';
ui = ui / 10;
i--;
} while(ui > 0);

for(i = (2 - d); i < 2; i++)
lcd_putchr(buf[i]);
}








unsigned char EByteWrite( unsigned char control,
unsigned int address, unsigned char data ){

IdleI2C();
SSPCON2bits.SEN = 1;
while ( SSPCON2bits.SEN );
if ( PIR2bits.BCLIF ){
return ( -1 );
} else {
SSPBUF = control;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-2);
}
PIR1bits.SSPIF = 0;

SSPBUF = address >> 8;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-3);
}
PIR1bits.SSPIF = 0;

SSPBUF = address;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-4);
}
PIR1bits.SSPIF = 0;

SSPBUF = data;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-5);
}
PIR1bits.SSPIF = 0;

SSPCON2bits.PEN = 1;
while ( SSPCON2bits.PEN );
PIR1bits.SSPIF = 0;
if ( PIR2bits.BCLIF ){
return ( -1 );
}
return ( 0 );
}
}

unsigned int EByteRead( unsigned char control, unsigned int address ){

IdleI2C();
SSPCON2bits.SEN = 1;
while ( SSPCON2bits.SEN );
if ( PIR2bits.BCLIF ) {
return ( -1 );
} else {
SSPBUF = control;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-2);
}
PIR1bits.SSPIF = 0;

SSPBUF = address >> 8;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-3);
}
PIR1bits.SSPIF = 0;

SSPBUF = address;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-4);
}
PIR1bits.SSPIF = 0;

SSPCON2bits.RSEN = 1;
while ( SSPCON2bits.RSEN );
if ( PIR2bits.BCLIF ){
return ( -5 );
} else {
SSPBUF = control+1;
while(SSPSTATbits.BF);
IdleI2C();
if ( SSPCON2bits.ACKSTAT ){
return(-6);
}
PIR1bits.SSPIF = 0;

SSPCON2bits.RCEN = 1;
while ( SSPCON2bits.RCEN );
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while ( SSPCON2bits.ACKEN );
PIR1bits.SSPIF = 0;

SSPCON2bits.PEN = 1;
while ( SSPCON2bits.PEN );
if ( PIR2bits.BCLIF ){
return ( -7 );
} else {
PIR1bits.SSPIF = 0;
return ( (unsigned int) SSPBUF );
}
}
}
}







void lcd_init(void){
Delay_20mS;
lcd_RS = 0;
lcd_w4(0x30);Delay_5mS;
lcd_w4(0x30);Delay_1mS;
lcd_w4(0x30);Delay_1mS;
lcd_w4(0x20);Delay_1mS;
lcd_c4(0x2E);
lcd_c4(0x08);
lcd_c4(0x0C);
lcd_c4(0x06);
lcd_c4(0x01);
}

void UserInit(void){

s = 0; sh = 0;

ss[0] = 0; ss[1] = 0; ss[2] = 0; ss[3] = 0;
ss[4] = 0; ss[5] = 0; ss[6] = 0; ss[7] = 0;

sss = 0; tr = 0;

a0 = 0; a1 = 0; a2 = 0; a3 = 0;

for(n=0;n<8;n++) a[n] = 0;
ii = 0; n = 0; b = 0; sum = 0; k = 0;

z1 = 0; z2 = 0; z3 = 0; z4 = 0;

sw = 0;

}






void main(void){

ADCON1 = 0x0F;
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTE = 0x00;
TRISA = 0b11111111;
TRISB = 0b00000000;
TRISC = 0b10110111;

UCONbits.USBEN = 0;
UCFGbits.UTRDIS = 1;
//RCSTAbits.SPEN = 0;

OpenI2C(MASTER, SLEW_ON);
SSPADD = 9;


OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF &
USART_ASYNCH_MODE & USART_EIGHT_BIT &
USART_CONT_RX & USART_BRGH_LOW, 155); //clock 48MHz, 4800 bps
  

UserInit();
lcd_init();


N = EByteRead(0xA0,0); //電源を切ってもEEPROMデータに追加できるため

lcd_clr();
lcd_locate(0, 3); lcd_puts(card);
lcd_locate(1, 0); lcd_puts(num); lcd_putui(N, 4);




while(1){




if(PORTAbits.RA5==0){ // モード切替
switch(sw){
case 0: sw = 1; break;
case 1: sw = 2; break;
case 2: {
sw = 0;

break;
}
default: break;
}

Delay_100mS; Delay_100mS;
}



if(sw == 0){ // カード入力、 数値入力、 EEPROM 記録


if(tr == 1){
tr = 0;
lcd_locate(0, 3); lcd_puts(card);
lcd_locate(1, 0); lcd_puts(num); lcd_putui(N, 4);
}



if(PORTCbits.RC4==0){ // 暗いときに サンプリング
s++; si = 0; Delay_1mS;
}

else{

sh++; Delay_1mS; // 明るいときに ii をクリヤ(ss[ii] の順番を合わせる)
if(sh > 3000){
sh = 0; ii = 0;
}


if(si == 0){
ss[ii] = s; s = 0; ii++;


if(ii > 8){ // カードの速度によらず 0、1 を区別する
ii = 0; sss = (ss[0] + ss[1] + ss[2])/3;

for(i=0;i<6;i++){
if(30 < ((ss[i+3]*100)/sss) && ((ss[i+3]*100)/sss) < 150) X[i] = 0;
if(150 < ((ss[i+3]*100)/sss)) X[i] = 1;
}
lcd_clr();
lcd_locate(1, 0);

lcd_putui(X[0], 1); lcd_putui(X[1], 1);
lcd_putui(X[2], 1); lcd_putui(X[3], 1); lcd_putui(X[4], 1);
lcd_putui(X[5], 1);
lcd_putui(sss, 4);
}
}
si = 1;

}

// 顧客データの照合
//for(i=0;i<6;i++){
//if(CN1[i] == X[i]) z1++;
//if(CN2[i] == X[i]) z2++;
//if(CN3[i] == X[i]) z3++;
//if(CN4[i] == X[i]) z4++;
//}
//if((z1==6)||(z2==6)||(z3==6)||(z4==6)){
//z1 = 0; z2 = 0; z3 = 0; z4 = 0;

if(((CN1[0] == X[0]) && (CN1[1] == X[1]) && (CN1[2] == X[2]) && \
(CN1[3] == X[3]) && (CN1[4] == X[4]) && (CN1[5] == X[5])) || \
((CN2[0] == X[0]) && (CN2[1] == X[1]) && (CN2[2] == X[2]) && \
(CN2[3] == X[3]) && (CN2[4] == X[4]) && (CN2[5] == X[5])) || \
((CN3[0] == X[0]) && (CN3[1] == X[1]) && (CN3[2] == X[2]) && \
(CN3[3] == X[3]) && (CN3[4] == X[4]) && (CN3[5] == X[5])) || \
((CN4[0] == X[0]) && (CN4[1] == X[1]) && (CN4[2] == X[2]) && \
(CN4[3] == X[3]) && (CN4[4] == X[4]) && (CN4[5] == X[5]))) {
Delay_100mS;

lcd_locate(0, 3); lcd_puts(input);
// 置数
if((PORTAbits.RA0==0)||(PORTAbits.RA1==0)||(PORTAbits.RA2==0)\
||(PORTAbits.RA3==0)||(PORTAbits.RA4==0)){

a0 = 0; a1 = 0; a2 = 0; a3 = 0;
if(PORTAbits.RA0==0) a0 = 1;
if(PORTAbits.RA1==0) a1 = 1;
if(PORTAbits.RA2==0) a2 = 1;
if(PORTAbits.RA3==0) a3 = 1;
a[n] = a3*8 + a2*4 + a1*2 + a0;
if(PORTAbits.RA4==0) a[n] = 0;

b = b*10 + a[n];
a[n] = 0;
n = n + 1;

Delay_100mS; Delay_100mS;

lcd_clr(); lcd_locate(0, 3); lcd_puts(input);
lcd_locate(1, 4); lcd_putui(b, 8);
}


if(PORTEbits.RE3==0){ // +/=
sum = sum + b;
b = 0; n = 0;
a0 = 0; a1 = 0; a2 = 0; a3 = 0;
for(n=0;n<8;n++) a[n] = 0;

lcd_clr(); lcd_locate(0, 3); lcd_puts(input);
lcd_locate(1, 4); lcd_putui(sum, 8);

Delay_100mS;
}


if(PORTCbits.RC0==0){ // 置数クリヤ
b = 0; n = 0;
a0 = 0; a1 = 0; a2 = 0; a3 = 0;
sum = 0;
for(n=0;n<8;n++) a[n] = 0;
Delay_100mS;

lcd_clr(); lcd_locate(0, 3); lcd_puts(input);
lcd_locate(1, 4); lcd_putui(b, 8);
}


if(PORTCbits.RC1==0){ // EEPROMへ記録
N++;

if(sum < b) sum = b; // +/=を押さない1回目の数値の場合

summ = sum;
suml = summ%256; summ = summ/256;
sumh = summ%256; summ = summ/256;
sumhh = summ%256;

wd = EByteWrite(0xA0,0,N);
Delay10KTCYx(25);
wdl = EByteWrite(0xA0,N*4,suml);
Delay10KTCYx(25);
wdh = EByteWrite(0xA0,N*4+1,sumh);
Delay10KTCYx(25);
wdhh = EByteWrite(0xA0,N*4+2,sumhh);
Delay10KTCYx(25);

CNw0 = EByteWrite(0xA0,10000+N*6,X[0]); Delay10KTCYx(25);
CNw1 = EByteWrite(0xA0,10000+N*6+1,X[1]); Delay10KTCYx(25);
CNw2 = EByteWrite(0xA0,10000+N*6+2,X[2]); Delay10KTCYx(25);
CNw3 = EByteWrite(0xA0,10000+N*6+3,X[3]); Delay10KTCYx(25);
CNw4 = EByteWrite(0xA0,10000+N*6+4,X[4]); Delay10KTCYx(25);
CNw5 = EByteWrite(0xA0,10000+N*6+5,X[5]); Delay10KTCYx(25);

rd = EByteRead(0xA0,0);
rdl = EByteRead(0xA0,N*4); rdh = EByteRead(0xA0,N*4+1);
rdhh = EByteRead(0xA0,N*4+2);
rdd = rdhh*65536 + rdh*256 + rdl;
lcd_clr(); lcd_locate(0, 2);
lcd_locate(1, 0); lcd_puts(num); lcd_putui(rd, 4);
lcd_puts(blank); lcd_putui(rdd, 8);

b = 0; n = 0;
a0 = 0; a1 = 0; a2 = 0; a3 = 0;
sum = 0;

for(i=0;i<6;i++){
X[i] = 0;
}
ss[0] = 0; ss[1] = 0; ss[2] = 0; ss[3] = 0;
ss[4] = 0; ss[5] = 0; ss[6] = 0; ss[7] = 0;

lcd_clr();
lcd_locate(0, 3); lcd_puts(card);
lcd_locate(1, 0); lcd_puts(num); lcd_putui(rd, 4);
Delay_100mS;
}
j = 0;
}
}




if(sw == 1){ // チェック

//lcd_clr();
lcd_locate(0, 3); lcd_puts(check);


if(PORTCbits.RC5==0){ //数値チェック
j++; jj = j;

rd = EByteRead(0xA0,0);
rdl = EByteRead(0xA0,j*4); rdh = EByteRead(0xA0,j*4+1); rdhh = EByteRead(0xA0,j*4+2);
rdd = rdhh*65536 + rdh*256 + rdl;

lcd_clr(); lcd_locate(0, 3); lcd_puts(check);
lcd_locate(1, 0);lcd_puts(num); lcd_putui(j, 3);
lcd_puts(blank); lcd_putui(rdd, 8);
Delay_100mS; Delay_100mS; Delay_100mS;
}

if(PORTCbits.RC0==0){ //間違えた数値を0にする
wdl = EByteWrite(0xA0,jj*4,0);
Delay10KTCYx(15);
wdh = EByteWrite(0xA0,jj*4+1,0);
Delay10KTCYx(15);
wdhh = EByteWrite(0xA0,jj*4+2,0);
Delay10KTCYx(15);

rd = EByteRead(0xA0,0);
rdl = EByteRead(0xA0,j*4); rdh = EByteRead(0xA0,j*4+1); rdhh = EByteRead(0xA0,j*4+2);
rdd = rdhh*65536 + rdh*256 + rdl;
lcd_clr(); lcd_locate(0, 3); lcd_puts(check);
lcd_locate(1, 0);lcd_puts(num); lcd_putui(jj, 3);
lcd_puts(blank); lcd_putui(rdd, 8);
Delay_100mS;
}

if(j >= rd) j = 0;
}





if(sw == 2){ // UART 送信、 EEPROM クリヤ

lcd_clr(); lcd_locate(0, 3); lcd_puts(trans);
Delay_100mS;

if(PORTCbits.RC2==0){
Delay_100mS; Delay_100mS;


for(i=0;i<23;i++) buf[i] =' '; // 最初に ダミー送信(無線の場合)
buf[23] = 0x0D; // 復帰
buf[24] = 0x0A; // 改行
putsUSART(buf);
Delay_20mS;

rd = EByteRead(0xA0,0);

for(k=1;k<rd+1;k++){

rd = EByteRead(0xA0,0);
rdl = EByteRead(0xA0,k*4); rdh = EByteRead(0xA0,k*4+1);
rdhh = EByteRead(0xA0,k*4+2);
rdd = rdhh*65536 + rdh*256 + rdl;

CNr0 = EByteRead(0xA0,10000+k*6); CNr1 = EByteRead(0xA0,10000+k*6+1);
CNr2 = EByteRead(0xA0,10000+k*6+2); CNr3 = EByteRead(0xA0,10000+k*6+3);
CNr4 = EByteRead(0xA0,10000+k*6+4); CNr5 = EByteRead(0xA0,10000+k*6+5);

buf[0] = '0'; buf[1] = '1'; buf[2] = ','; // 店番号 01

buf[3] = CNr0+'0'; buf[4] = CNr1+'0'; buf[5] = CNr2+'0';
buf[6] = CNr3+'0'; buf[7] = CNr4+'0'; buf[8] = CNr5+'0';
buf[9] = ',';

for(i=10;i<18;i++) buf[i] = ' ';
i = 17;
do{
buf[i] = (rdd%10) + '0';
rdd = rdd/10;
i--;
} while(rdd > 0);
buf[18] = ',';

kk = k;
for(i=19;i<23;i++) buf[i] = ' ';
i = 22;
do{
buf[i] = (kk%10) + '0';
kk = kk/10;
i--;
} while(kk > 0);

buf[23] = 0x0D; // 復帰
buf[24] = 0x0A; // 改行


putsUSART(buf);
Delay_20mS;
}

rd = EByteRead(0xA0,0);

lcd_clr(); lcd_locate(0, 3); lcd_puts(trans);
lcd_locate(1, 5); lcd_puts(transed);
Delay_100mS; Delay_100mS; Delay_100mS; Delay_100mS; Delay_100mS;
}


if(PORTCbits.RC0==0){ // メモリ全消去
Delay_100mS; Delay_100mS;

rd = EByteRead(0xA0,0);

for(i=0;i<rd+1;i++){
wdl = EByteWrite(0xA0,i*4,0);
Delay10KTCYx(15);
wdh = EByteWrite(0xA0,i*4+1,0);
Delay10KTCYx(15);
wdhh = EByteWrite(0xA0,i*4+2,0);
Delay10KTCYx(15);

CNw0 = EByteWrite(0xA0,10000+i*6,0); Delay10KTCYx(15);
CNw1 = EByteWrite(0xA0,10000+i*6+1,0); Delay10KTCYx(15);
CNw2 = EByteWrite(0xA0,10000+i*6+2,0); Delay10KTCYx(15);
CNw3 = EByteWrite(0xA0,10000+i*6+3,0); Delay10KTCYx(15);
CNw4 = EByteWrite(0xA0,10000+i*6+4,0); Delay10KTCYx(15);
CNw5 = EByteWrite(0xA0,10000+i*6+5,0); Delay10KTCYx(15);
}

rd = EByteRead(0xA0,0);
lcd_clr(); lcd_locate(0, 3); lcd_puts(trans);
lcd_locate(1, 5); lcd_puts(cleared);
Delay_100mS; Delay_100mS; Delay_100mS; Delay_100mS; Delay_100mS;

N = 0;
}
for(i=0;i<6;i++){
X[i] = 0;
}
tr = 1;

}

}
}